/*
 * To change this template, choose Tools | Templates
 * and open the template in the editor.
 */
package br.com.ufc.model.data;

import br.com.ufc.exception.IntegrationException;
import br.com.ufc.model.Tarefa;
import br.com.ufc.model.TarefaDataBase;
import br.com.ufc.model.TarefaTO;
import br.com.ufc.util.HibernateUtil;
import java.util.List;
import org.apache.log4j.Logger;
import org.hibernate.HibernateException;
import org.hibernate.Session;
import org.hibernate.Transaction;

/**
 *
 * @author Paulo Silva
 */
public class TarefaPersistence{

    private static final Logger LOGGER = Logger.getLogger(TarefaPersistence.class);

    public Boolean inserirTarefa(TarefaDataBase tarefa) throws IntegrationException {
        Session s = null;
        try {
            s = HibernateUtil.getSession();
            Transaction tran = s.beginTransaction();
            s.save(tarefa);
            tran.commit();
        } catch (HibernateException e) {
            LOGGER.fatal(e.getMessage());
            throw new IntegrationException("Erro ao inserir tarefa");
        } finally {
            s.close();
        }
        return true;
    }

    public TarefaDataBase consultarTarefa(Long codigo) throws IntegrationException {
        Session s = null;
        try {
            s = HibernateUtil.getSession();
            //TarefaDataBase t = (TarefaDataBase) s.load(TarefaDataBase.class, codigo);
            return (TarefaDataBase) s.get(TarefaDataBase.class, codigo);
            //TarefaDataBase tarefaAux = new TarefaDataBase();
            //this.clonarTarefa(t, tarefaAux);
            //return tarefaAux;
        } catch (HibernateException e) {
            LOGGER.error(e);
            throw new IntegrationException("Erro ao consultar tarefa");
        } finally {
            s.close();
        }
    }

    public Boolean alterarTarefa(TarefaDataBase tarefa) throws IntegrationException {
        Session s = null;
        try {
            s = HibernateUtil.getSession();
            //Recupera a tarefa, no seu estado original
            TarefaDataBase t = (TarefaDataBase) s.get(TarefaDataBase.class, tarefa.getCodigo());
            if (t != null) {
                this.clonarTarefa(tarefa, t);
                Transaction tran = s.beginTransaction();
                s.save(t);
                tran.commit();
            } else {
                return false;
            }
        } catch (HibernateException e) {
            LOGGER.fatal(e.getMessage());
            throw new IntegrationException("Erro ao alterar tarefa");
        } finally {
            s.close();
        }
        return true;
    }
    
    public Boolean incrementarImportancia(Tarefa tarefa){
        Session s = null;
        try {
            s = HibernateUtil.getSession();
            //Recupera a tarefa, no seu estado original
            TarefaDataBase t = (TarefaDataBase) s.get(TarefaDataBase.class, tarefa.getCodigo());
            if (t != null) {
                //this.clonarTarefa(tarefa, t);
                t.incrementarImportancia();
                Transaction tran = s.beginTransaction();
                s.save(t);
                tran.commit();
            } else {
                return false;
            }
        } catch (HibernateException e) {
            LOGGER.fatal(e.getMessage());
            //throw new IntegrationException("Erro ao alterar tarefa");
        } finally {
            s.close();
        }
        return true;
    }

    public Boolean deletarTarefa(TarefaDataBase tarefa) {
        Session s = null;
        try {
            s = HibernateUtil.getSession();
            //Recupera a tarefa, no seu estado original
            TarefaDataBase t = (TarefaDataBase) s.load(TarefaDataBase.class, tarefa.getCodigo());
            //if (t != null) {
            Transaction tran = s.beginTransaction();
            s.delete(t);
            tran.commit();
            //} else {
            //    return false;
            //}
        } catch (Exception e) {
            LOGGER.fatal("Erro ao deletar tarefa" + e.getMessage());
        } finally {
            s.close();
        }
        return true;
    }

    public TarefaTO listarTarefas() {
        Session s = null;
        try {
            s = HibernateUtil.getSession();
            TarefaTO to = new TarefaTO();
            to.setListaTarefas(s.createCriteria(TarefaDataBase.class).list());
            return to;
        } catch (Exception e) {
            LOGGER.fatal("Erro ao listar tarefas" + e.getMessage());
        } finally {
            s.close();
        }
        return null;
    }

    public void iniciarTarefa(Long codigo) throws IntegrationException {
        Session s = null;
        try {
            s = HibernateUtil.getSession();
            //Recupera a tarefa, no seu estado original
            TarefaDataBase t = (TarefaDataBase) s.get(TarefaDataBase.class, codigo);
            if (t != null) {
                //this.clonarTarefa(tarefa, t);
                Transaction tran = s.beginTransaction();
                t.iniciarTarefa();
                s.save(t);
                tran.commit();
            } else {
                throw new IntegrationException("Tarefa não localizada no banco de dados");
            }
        } catch (HibernateException e) {
            LOGGER.fatal(e.getMessage());
            throw new IntegrationException("Erro ao iniciar tarefa");
        } finally {
            s.close();
        }
    }

    public void cancelarTarefa(Long codigo) throws IntegrationException {
        Session s = null;
        try {
            s = HibernateUtil.getSession();
            //Recupera a tarefa, no seu estado original
            TarefaDataBase t = (TarefaDataBase) s.get(TarefaDataBase.class, codigo);
            if (t != null) {
                //this.clonarTarefa(tarefa, t);
                Transaction tran = s.beginTransaction();
                t.cancelarTarefa();
                s.save(t);
                tran.commit();
            } else {
                throw new IntegrationException("Tarefa não localizada no banco de dados");
            }
        } catch (HibernateException e) {
            LOGGER.fatal(e.getMessage());
            throw new IntegrationException("Erro ao cancelar tarefa");
        } finally {
            s.close();
        }
    }

    public void removerTarefa(Long codigo) throws IntegrationException {
        Session s = null;
        try {
            s = HibernateUtil.getSession();
            //Recupera a tarefa, no seu estado original
            TarefaDataBase t = (TarefaDataBase) s.get(TarefaDataBase.class, codigo);
            if (t != null) {
                //this.clonarTarefa(tarefa, t);
                Transaction tran = s.beginTransaction();
                s.delete(t);
                tran.commit();
            } else {
                throw new IntegrationException("Tarefa não localizada no banco de dados");
            }
        } catch (HibernateException e) {
            LOGGER.fatal(e.getMessage());
            throw new IntegrationException("Erro ao cancelar tarefa");
        } finally {
            s.close();
        }
    }

    public void reiniciarTarefa(Long codigo) throws IntegrationException {
        Session s = null;
        try {
            s = HibernateUtil.getSession();
            //Recupera a tarefa, no seu estado original
            TarefaDataBase t = (TarefaDataBase) s.get(TarefaDataBase.class, codigo);
            if (t != null) {
                //this.clonarTarefa(tarefa, t);
                Transaction tran = s.beginTransaction();
                if (t.reinicarTarefa() == false) {
                    throw new IntegrationException("Só é possivel reiniciar tarefas com status F - finalizada!");
                }
                s.save(t);
                tran.commit();
            } else {
                throw new IntegrationException("Tarefa não localizada no banco de dados");
            }
        } catch (HibernateException e) {
            LOGGER.fatal(e.getMessage());
            throw new IntegrationException("Erro ao reiniciar tarefa");
        } finally {
            s.close();
        }
    }

    public void encerrarTarefa(Long codigo, Double valorCobrado) throws IntegrationException {
        Session s = null;
        try {
            s = HibernateUtil.getSession();
            //Recupera a tarefa, no seu estado original
            TarefaDataBase t = (TarefaDataBase) s.get(TarefaDataBase.class, codigo);
            if (t != null) {
                //this.clonarTarefa(tarefa, t);
                Transaction tran = s.beginTransaction();
                t.encerrarTarefa(valorCobrado);
                s.save(t);
                tran.commit();
            } else {
                throw new IntegrationException("Tarefa não localizada no banco de dados");
            }
        } catch (HibernateException e) {
            LOGGER.fatal(e.getMessage());
            throw new IntegrationException("Erro ao encerrar tarefa");
        } finally {
            s.close();
        }
    }

    public Boolean encerrarTodasTarefas() {
        Session s = null;
        try {
            s = HibernateUtil.getSession();
            TarefaTO to = new TarefaTO();
            List<Tarefa> lista = s.createCriteria(TarefaDataBase.class).list();

            for (Tarefa t : lista) {
                Tarefa tInterna = (TarefaDataBase) s.get(TarefaDataBase.class, t.getCodigo());
                tInterna.encerrarTarefa(0D);
                Transaction tran = s.beginTransaction();
                s.save(tInterna);
                tran.commit();
            }
            return true;
        } catch (Exception e) {
            LOGGER.fatal("Erro ao listar tarefas" + e.getMessage());
        } finally {
            s.close();
        }
        return false;
    }

    private void clonarTarefa(TarefaDataBase tOrigem, TarefaDataBase tDestino) {
        tDestino.setCodigo(tOrigem.getCodigo());
        tDestino.setData(tOrigem.getData());
        tDestino.setDescricao(tOrigem.getDescricao());
        tDestino.setDuracao(tOrigem.getDuracao());
        tDestino.setHoraInicio(tOrigem.getHoraInicio());
        tDestino.setImportancia(tOrigem.getImportancia());
        tDestino.setLocal(tOrigem.getLocal());
        tDestino.setStatus(tOrigem.getStatus());
        tDestino.setUrgencia(tOrigem.getUrgencia());
        tDestino.setValorCobrado(tOrigem.getValorCobrado());
        tDestino.setValorHora(tOrigem.getValorHora());

    }
}
